package com.sright.bcard.common.biz.manager.impl;

import com.alibaba.fastjson.JSONObject;
import com.sright.bcard.common.biz.manager.WxappManager;
import com.sright.bcard.common.service.share.dto.common.ContentCheckDTO;
import com.sright.bcard.common.service.share.dto.page.PageDTO;
import com.sright.bcard.common.service.share.dto.page.PageParamRequest;
import com.sright.bcard.common.service.share.enums.BucketTypeEnum;
import com.sright.bcard.common.service.share.enums.WechatPushTemplateEnum;
import com.sright.bcard.common.service.share.enums.WxappStatusEnum;
import com.sright.bcard.common.service.share.okhttp.HttpUtils;
import com.sright.bcard.common.service.share.utils.*;
import com.sright.bcard.common.service.share.dto.common.QrCodeDTO;
import com.sright.bcard.common.service.share.dto.common.WechatTemplateDTO;
import com.sright.bcard.common.service.share.dto.common.WxappDTO;
import com.sright.bcard.common.service.share.dto.common.ContentCheckDO;
import com.sright.bcard.common.share.request.WechatTemplateDO;
import com.sright.bcard.content.dal.dao.WxappConfDAO;
import com.sright.bcard.content.dal.dao.WxappDAO;
import com.sright.bcard.content.dal.entity.WxappConfDO;
import com.sright.bcard.content.dal.entity.WxappDO;
import com.sright.common.response.SrightResponse;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
import org.springframework.util.ResourceUtils;
import org.springframework.web.client.RestTemplate;

import java.io.File;
import java.util.*;

@Component
@Slf4j
public class WxappManagerImpl implements WxappManager {

    @Value("${WXAPP_APPID}")
    private String appId;

    @Value("${WXAPP_APPSECRET}")
    private String appSecret;

    @Value("${OFFICIAL_WXAPP_APPID}")
    private String officialAppId;

    @Autowired
    private WxappDAO wxappDAO;

    @Autowired
    private WxappConfDAO wxappConfDAO;

    @Autowired
    private JedisUtil jedisUtil;

    @Override
    public PageDTO<WxappDTO> wxappList(PageParamRequest pageParamRequest) {
        // 查询总的条数
        Integer count = wxappDAO.count(pageParamRequest);
        PageDTO<WxappDTO> pageDTO = new PageDTO<>();
        // 分页查询数据
        List<WxappDO> WxappDOS = wxappDAO.pageList(pageParamRequest);
        if(CollectionUtils.isNotEmpty(WxappDOS)) {
            // DTO 转化为 DO
            List<WxappDTO> WxappDTOS = new ArrayList<>();
            DataConvertUtils.convertDOList2DTOList(WxappDOS, WxappDTOS, WxappDTO.class);
            pageDTO.setData(WxappDTOS);
            pageDTO.setCount(count);
            return pageDTO;
        }
        return new PageDTO<>();
    }

    @Override
    public Integer status(WxappDTO wxappDTO) {
        // 查询修改之前的状态
        WxappDO wxappDO = wxappDAO.selectById(wxappDTO.getId());
        final Integer[] status = {0};
        if(WxappStatusEnum.HIDED.getValue().intValue() == wxappDO.getStatus().intValue()) {
            status[0] = WxappStatusEnum.DELETED.getValue();
        }
        if(WxappStatusEnum.DELETED.getValue().intValue() == wxappDO.getStatus().intValue()) {
            status[0] = WxappStatusEnum.HIDED.getValue();
        }
        return wxappDAO.status(wxappDTO.getId(), status[0], wxappDTO.getEnterpriseId());
    }

    @Override
    public Integer deleteStatus(Long id) {
        return wxappDAO.deleteStatus(id);
    }

    @Override
    public SrightResponse getEnterpriseWxappInfo(Long enterpriseId) {
        WxappDO wxappDO = wxappDAO.selectByEnterpriseId(enterpriseId);
        return SrightResponse.defaultSuccess(wxappDO);
    }

    @Override
    public SrightResponse createQrCode(String path) throws Exception {
        //获取accesstoken
        String accessToken = getAccessToken();
        String filePath = ResourceUtils.getURL("classpath:").getPath();
        File upload = new File(filePath,"static/qrcode/");
        if(!upload.exists()) {
            upload.mkdirs();
        }

        UUID uuid = UUID.randomUUID();
        String fileName = "qrcode" + uuid.toString() + ".png";
        String pathName = upload.getAbsolutePath() + File.separator +fileName;
        //生成二维码并保存到本地

        String qrcode = WxappUtils.getMiniQrCode(accessToken,pathName,path);
        //上传到阿里云
        String url = AliyunUitls.uploadLocalFile(BucketTypeEnum.STATIC.getValue(),"qrcode/" + fileName,qrcode);
        //删除本地文件
        new File(pathName).delete();
        QrCodeDTO qrCodeDTO = new QrCodeDTO();
        qrCodeDTO.setUrl(url);
        return SrightResponse.defaultSuccess(qrCodeDTO);
    }


    @Override
    public SrightResponse getPreviewCode(Long userId) throws Exception {
        String code = jedisUtil.get("previewCode:" + userId);
        if (code == null) {
            String path = "pages/card/main?t=3&cardId=&userId=" + userId + "&lang=zh&u=1";
            code = createQrCodeBase64(path);
            jedisUtil.set("previewCode:" + userId,code);
        }
        return SrightResponse.defaultSuccess(code);
    }


    @Override
    public SrightResponse getInviteCode(Long enterpriseId) throws Exception {
        String code = jedisUtil.get("inviteCode:" + enterpriseId);
        if (code == null) {
            String path = "pages/card_edit/main?eid=" + enterpriseId;
            code = createQrCodeBase64(path);
            jedisUtil.set("inviteCode:" + enterpriseId,code);
        }
        return SrightResponse.defaultSuccess(code);
    }

    protected String createQrCodeBase64(String path) throws Exception {
        String accessToken = getAccessToken();
        String filePath = ResourceUtils.getURL("classpath:").getPath();
        File upload = new File(filePath,"static/qrcode/");
        if(!upload.exists()) {
            upload.mkdirs();
        }

        UUID uuid = UUID.randomUUID();
        String fileName = "qrcode" + uuid.toString() + ".png";
        String pathName = upload.getAbsolutePath() + File.separator +fileName;
        //生成二维码并保存到本地

        String qrcode = WxappUtils.getMiniQrCode(accessToken,pathName,path);
        String result = WxappUtils.GetImageStr(qrcode);

        return result;
    }

    @Override
    public void sendVisitorTemplateMessage(Map<String, String> map) throws Exception {
        //根据map封装信息
        map.put("templateId", WechatPushTemplateEnum.NEWVISITOR.getValue());
        String first;
        if (map.get("userType").equals("1")) {
            first = "有访客正在查看你的企业名片";
        } else {
            first = "有访客正在查看你的个人名片";
        }

        Map<String,String > msgMap = new HashMap<>();
        msgMap.put("first",first);
        msgMap.put("keyword1",map.get("nickname"));
        msgMap.put("keyword2","视然名片");
        msgMap.put("keyword3",map.get("parentNickname"));
        msgMap.put("keyword4",DateTimeUtils.formatString(new Date(),DateTimeUtils.DATE_TIME_STYLE));
        msgMap.put("remark","如需关闭通知，请在视然名片小程序的设置中处理");
        sendTemplateMessage(map,assembleData(msgMap));
    }

    @Override
    public JSONObject wechatLogin(String code) {
        String params = "appid=" + appId + "&secret=" + appSecret + "&js_code=" + code + "&grant_type=authorization_code";
        String s= HttpUtils.sendGet("https://api.weixin.qq.com/sns/jscode2session", params);
        JSONObject jsonObject = JSONObject.parseObject(s);
        return jsonObject;
    }

    @Override
    public ContentCheckDTO checkContent(String content) {
        RestTemplate restTemplate = new RestTemplate();
        String url = null;
        try {
            url = "https://api.weixin.qq.com/wxa/msg_sec_check?access_token=" + getAccessToken();
        } catch (Exception e) {
            e.printStackTrace();
        }
        ContentCheckDO contentCheckDO = new ContentCheckDO();
        contentCheckDO.setContent(content);
        ContentCheckDTO result = restTemplate.postForObject(url,contentCheckDO,ContentCheckDTO.class);
        System.out.println(result.toString());
        return result;
    }

    @Override
    public void sendDataStatisticsTemplateMessage(Map<String, String> map) throws Exception {
        //根据map封装信息
        map.put("templateId", WechatPushTemplateEnum.DAYVISITOTDATA.getValue());

        String first;
        if (map.get("userType").equals("1")) {
            first = "今天你的企业名片客流数据";
        } else {
            first = "今天你的个人名片客流数据";
        }

        Map<String,String > msgMap = new HashMap<>();
        msgMap.put("first",first);
        msgMap.put("keyword1",DateTimeUtils.formatString(new Date(),DateTimeUtils.DATE_TIME_STYLE));
        msgMap.put("keyword2",map.get("countString"));
        msgMap.put("remark","如需关闭通知，请在视然名片小程序的设置中处理");

        sendTemplateMessage(map,assembleData(msgMap));
    }

    protected void sendTemplateMessage(Map<String, String> map, Map<String, WechatTemplateDO.TemplateMsgDO.DataDO> dataMap) throws Exception {
        WechatTemplateDO wechatTemplateDO = new WechatTemplateDO();
        wechatTemplateDO.setTouser(map.get("openid"));
        WechatTemplateDO.TemplateMsgDO templateMsgDO = new WechatTemplateDO.TemplateMsgDO();
        templateMsgDO.setData(dataMap);
        templateMsgDO.setAppid(officialAppId);
        templateMsgDO.setTemplate_id(map.get("templateId"));
        if (StringUtils.isNotEmpty(map.get("userType"))) {
            WechatTemplateDO.TemplateMsgDO.MiniprogramDO miniprogramDO = new WechatTemplateDO.TemplateMsgDO.MiniprogramDO();
            miniprogramDO.setAppid(appId);
            miniprogramDO.setPagepath("pages/hot/main?u=" + map.get("userType"));
            templateMsgDO.setMiniprogram(miniprogramDO);
        }
        templateMsgDO.setUrl("");
        wechatTemplateDO.setMp_template_msg(templateMsgDO);

        RestTemplate restTemplate = new RestTemplate();
        String url = "https://api.weixin.qq.com/cgi-bin/message/wxopen/template/uniform_send?access_token=" + getAccessToken();
        WechatTemplateDTO wechatTemplateDTO = restTemplate.postForObject(url,wechatTemplateDO,WechatTemplateDTO.class);
        if (wechatTemplateDTO.getErrcode() != 0) {
            log.info("sendVisitorTemplateMessage 访客服务号推送结果 errcode : {}, errmsg :  {}", wechatTemplateDTO.getErrcode(), wechatTemplateDTO.getErrmsg());
        }
    }

    protected Map<String, WechatTemplateDO.TemplateMsgDO.DataDO> assembleData(Map<String, String> map) {
        Map<String, WechatTemplateDO.TemplateMsgDO.DataDO> resultMap = new HashMap<String, WechatTemplateDO.TemplateMsgDO.DataDO>();
        for(Map.Entry<String, String> entry:map.entrySet()){
            WechatTemplateDO.TemplateMsgDO.DataDO dataDO = new WechatTemplateDO.TemplateMsgDO.DataDO();
            dataDO.setValue(entry.getValue());
            dataDO.setColor("#000000");
            resultMap.put(entry.getKey(),dataDO);
        }
        return resultMap;
    }

    /**
     * 获取accessToken
     * @return
     * @throws Exception
     */
    public String getAccessToken() throws Exception {
        String accessToken;
        Date now = new Date();
        WxappConfDO wxappConfDO = wxappConfDAO.selectById(1L);
        if (wxappConfDO == null) {
            accessToken = WxappUtils.getAccessToken(appId,appSecret);
            WxappConfDO wxappConfDO1 = new WxappConfDO();
            wxappConfDO1.setName("名片小程序");
            wxappConfDO1.setAppId(appId);
            wxappConfDO1.setAppSecret(appSecret);
            wxappConfDO1.setAccessToken(accessToken);
            wxappConfDO1.setExpiresIn(new Date(now.getTime() + 7050 * 1000));
            wxappConfDO1.setId(1L);
            wxappConfDAO.insert(wxappConfDO1);
        } else {
            if (wxappConfDO.getAccessToken().equals("") || now.compareTo(wxappConfDO.getExpiresIn()) > 0) {
                accessToken = WxappUtils.getAccessToken(appId,appSecret);
                wxappConfDO.setAccessToken(accessToken);
                wxappConfDO.setExpiresIn(new Date(now.getTime() + 7050 * 1000));
                wxappConfDAO.updateSelective(wxappConfDO);
            } else {
                accessToken = wxappConfDO.getAccessToken();
            }
        }
        return accessToken;
    }
}
